package com.xinghe.sharedevice.service.impl;

import cn.hutool.core.stream.CollectorUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.share.common.core.utils.bean.BeanUtils;
import com.xinghe.sharedevice.domain.Cabinet;
import com.xinghe.sharedevice.domain.Station;
import com.xinghe.sharedevice.domain.StationLocation;
import com.xinghe.sharedevice.domain.vo.StationVo;
import com.xinghe.sharedevice.service.ICabinetService;
import com.xinghe.sharedevice.service.IDeviceService;
import com.xinghe.sharedevice.service.IStationService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metrics;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 星河一叶Ck
 * @date 2025/5/29
 */

@Service
@RequiredArgsConstructor
public class DeviceServiceImpl implements IDeviceService {

    private final MongoTemplate mongoTemplate;
    private final IStationService stationService;
    private final ICabinetService cabinetService;

    @Override
    public List<StationVo> nearbyStation(String latitude, String longitude) {
        //坐标，确定中心点
        // GeoJsonPoint(double x, double y) x 表示经度，y 表示纬度。
        GeoJsonPoint geoJsonPoint = new GeoJsonPoint(
                Double.parseDouble(longitude), Double.parseDouble(latitude));

        // 半径
        Distance distance = new Distance(5, Metrics.KILOMETERS);
        // 画了一个圆圈
        Circle circle = new Circle(geoJsonPoint, distance);
        // 条件 where里面填的是 实体类里面我们对应的一个属性名是location 当前位置
        Query query = Query.query(Criteria
                .where("location")
                // .withinSphere(circle)：这一条件表明查询要匹配的文档，其location字段必须处于一个球形区域内。
                .withinSphere(circle));

        List<StationLocation> stationLocationList = mongoTemplate
                .find(query, StationLocation.class);

        if (CollectionUtils.isEmpty(stationLocationList)) return null;

        // 组装数据
        // 将站点id全部给弄出来
        List<Long> stationIdList = stationLocationList.stream()
                .map(StationLocation::getStationId).collect(Collectors.toList());
        List<Station> stationList = stationService.list(new LambdaQueryWrapper<Station>()
                .in(Station::getId, stationIdList)
                .isNotNull(Station::getCabinetId)); // 排除cabinetId字段为null的记录

        // 获取柜机id列表
        List<Long> cabinetIdList = stationList.stream().map(Station::getCabinetId)
                .collect(Collectors.toList());

        //获取柜机id与柜机信息Map
        Map<Long, Cabinet> cabinetIdToCabinetMap = cabinetService.listByIds(cabinetIdList)
                .stream()
                // id 关联对应的cabinet柜机信息
                .collect(Collectors.toMap(Cabinet::getId, cabinet -> cabinet));

        // 最后的拼接存储到集合
        List<StationVo> stationVoList = new ArrayList<>();
        stationList.forEach(station -> {
            StationVo stationVo = new StationVo();
            BeanUtils.copyProperties(station, stationVo);

            // 获取柜机信息
            Cabinet cabinet = cabinetIdToCabinetMap.get(station.getCabinetId());
            //可用充电宝数量大于0，可借用
            if (cabinet.getAvailableNum() > 0) {
                stationVo.setIsUsable("1");
            } else {
                stationVo.setIsUsable("0");
            }

            // 获取空闲插槽数量大于0，可归还
            if (cabinet.getFreeSlots() > 0) {
                stationVo.setIsReturn("1");
            } else {
                stationVo.setIsReturn("0");
            }

            stationVoList.add(stationVo);
        });
        return stationVoList;
    }
}
